/******************************************************************************
 *  _____     _____
 *  \  __\    \  __\
 *   \ \_\\    \ \_\\
 *    \  __\SS  \  __\roject
 *     \_\       \_\
 *
 * Mateusz Maciąg, Rafał Urbański
 * Komputerowe Systemy Sterowania
 *****************************************************************************/

#ifndef SIMULATORSETTINGS_H
#define SIMULATORSETTINGS_H

#include "MainWindow.h"
#include "SimInterface/ISimulator.h"
#include "ARXConfigurator.h"
#include "ControllerDesigner.h"
#include "InputDesigner.h"
#include "NonlinDesigners/NolinearDesignerBase.h"

#include <QDialog>
#include <QListWidgetItem>
#include <QMetaType>

#include <utility>

#include <vector>
#include <string>

namespace Ui {
    class SimulatorSettings;
}

// Deklaracje zapowiadające
class MainWindow;

/**
    Klasa okna od ustawień symulacji.

    W zasadzie określa całą logikę programu (z wyjątkiem
    paru funkcji w klasie MainWindow). Daje pełną kontrolę
    nad tym co się dzieje w symulacji.
*/
class SimulatorSettings : public QDialog
{
    Q_OBJECT

public:
    //explicit SimulatorSettings(QWidget *parent = 0);

    /**
        Konstruktor klasy okna.
        Zmodyfikowano parametry konstruktora w zględem domyślnych
        generowanych przez Qt. Podany obiekt musi być instancją
        klasy MainWindow.

        \param[in] parent Okno rodzica, koniecznie MainWindow.
    */
    explicit SimulatorSettings(MainWindow *parent = 0);
    ~SimulatorSettings();

    /**
        Łączy to okno z obiektem symulatora.
    */
    void attachSimulator(RafMat::SimInterface::ISimulatorSPtr simPtr);

    /** Odświeża widok całego modelu symulatora */
    void refreshAll();

private slots:
    void on_btnInsert_clicked();
    void on_btnDelete_clicked();
    void on_modelChain_currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous);
    void on_btnReset_clicked();
    void on_btnStart_clicked();
    void on_btnStop_clicked();
    void on_btnStep_clicked();
    void on_speedSlider_valueChanged(int value);
    void on_cbEnableControl_toggled(bool checked);
    void on_controllerList_currentIndexChanged(int index);
    void on_btnCtrlApplySettings_clicked();
    void on_btnAddInput_clicked();
    void on_inputChain_currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous);
    void on_btnApplyInput_clicked();
    void on_btnRemoveInput_clicked();

    void on_cbNonlinType_currentIndexChanged(int index);

    void on_btnApplyNLSettings_clicked();

    void on_edHistoryDepth_valueChanged(int arg1);

    void on_cbPlotStyle_currentIndexChanged(const QString &arg1);

    void on_cbAntiAliasing_clicked(bool checked);

    void on_doubleSpinBox_valueChanged(double arg1);

    void on_cbEnableExternalPlant_toggled(bool checked);

    void on_btnExtApply_clicked();

    void on_cbEnableCapture_toggled(bool checked);

    void on_btnStartCapture_clicked();

    void on_btnStopCapture_clicked();

    void on_fileCapturePath_editingFinished();

private:
    // Inicjalizacja list:
    void initializeCtrlTab();
    void initializeInputTab();
    void initializeOutNLTab();

    void updateControllerView();
    void updateOutputView();

    typedef std::pair<std::string, std::string> StringPair;
    typedef std::vector<StringPair> StringPairVector;

    StringPairVector parseExtParams(std::string text);

    RafMat::SimInterface::ISimulator::ControllerType currentControllerType;
    RafMat::SimInterface::ISimulator::NonlinearityType currentNLType;

    // Pomocnicze funkcje:
    RafMat::SimInterface::IConfigurableSPtr obtainInputConfFromListItem(QListWidgetItem *item);

    void insertModelToList(RafMat::SimInterface::IDiscreteObjectSPtr obj);

    // Pola prywatne:
    ControllerDesigner      *m_currentCtrlDesigner;
    InputDesigner           *m_currentInputDesigner;
    MainWindow              *m_mainWindow;
    Ui::SimulatorSettings   *ui;
    ARXConfigurator         *m_arxConfigurator;

    NonlinearDesignerBase   *m_currentNLDesigner;

    bool forceControllerViewUpdate;
    bool forceNLViewUpdate;

    RafMat::SimInterface::ISimulatorSPtr m_simulatorPtr;
};

/** Alias na typ pary: wskaźnik na konfigurację wejścia - typ wejścia. */
typedef std::pair<RafMat::SimInterface::IConfigurableSPtr,
                  RafMat::SimInterface::ISimulator::InputType> InputConfPair;

Q_DECLARE_METATYPE(InputConfPair)

#endif // SIMULATORSETTINGS_H





